You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
4.9 KiB
203 lines
4.9 KiB
<script context="module">
|
|
export function preload({params}) {
|
|
return this.fetch(`${params.name}.json`).then(r => r.json()).then(({name, collection, error}) => {
|
|
return { name, collection };
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
import { onMount } from "svelte";
|
|
import capitalize from "capitalize";
|
|
|
|
import Page from "../components/Page.svelte";
|
|
import Selector from "../components/Selector.svelte";
|
|
|
|
export let name;
|
|
export let collection;
|
|
|
|
/** @type {import("../rust/namegen-wasm").default} */
|
|
let generator = null;
|
|
let selectedSuffix = "";
|
|
let selectedFormat = "";
|
|
let generatedFormat = "";
|
|
let generatedSuffix = "";
|
|
let result = ""
|
|
let failed = false;
|
|
let buffer = [];
|
|
let formats = [];
|
|
let suffixes = [];
|
|
|
|
let loaded = "";
|
|
let mounted = false;
|
|
|
|
function reload() {
|
|
loaded = name.name;
|
|
|
|
import("../rust/namegen-wasm").then(({load, default: NameGenerator}) => {
|
|
return load().then(() => {
|
|
console.log("Setting up", name.name);
|
|
generator = new NameGenerator(name.data);
|
|
})
|
|
}).catch(() => {
|
|
failed = true;
|
|
}).finally(() => {
|
|
loaded = name.name;
|
|
})
|
|
}
|
|
|
|
function generate() {
|
|
if (loaded !== name.name) {
|
|
return;
|
|
}
|
|
|
|
let format = `${selectedFormat}:${selectedSuffix}`;
|
|
if (!name.data.formats.find(f => f.name === format)) {
|
|
format = selectedFormat;
|
|
}
|
|
if (!name.data.formats.find(f => f.name === format)) {
|
|
return;
|
|
}
|
|
|
|
if (generator !== null) {
|
|
if (buffer.length === 0) {
|
|
console.time("Generate 64 names");
|
|
buffer = generator.generateMany(format, 64);
|
|
console.timeEnd("Generate 64 names");
|
|
}
|
|
|
|
result = buffer.pop();
|
|
} else {
|
|
result = name.examples[format][Math.floor(Math.random() * name.examples[format].length)]
|
|
}
|
|
|
|
generatedFormat = selectedFormat;
|
|
generatedSuffix = selectedSuffix;
|
|
}
|
|
|
|
onMount(() => {
|
|
mounted = true;
|
|
})
|
|
|
|
$: {
|
|
if (mounted && loaded !== name.name) {
|
|
generator = null;
|
|
buffer = [];
|
|
generatedFormat = "";
|
|
generatedSuffix = "";
|
|
selectedFormat = "";
|
|
selectedSuffix = "";
|
|
reload();
|
|
}
|
|
}
|
|
|
|
$: {
|
|
if (mounted && (selectedFormat !== generatedFormat || selectedSuffix !== generatedSuffix)) {
|
|
buffer = [];
|
|
generate();
|
|
}
|
|
}
|
|
|
|
$: {
|
|
const formatNames = name.data.formats.map(f => f.name.split(":")[0]).filter((f, i, a) => !a.slice(0, i).includes(f));
|
|
const suffixNames = name.data.formats.map(s => s.name.split(":")[1]).filter(s => s).filter((s, i, a) => !a.slice(0, i).includes(s));
|
|
const formatLabels = formatNames.map(n => name.metadata[`formatLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
|
|
const suffixLabels = suffixNames.map(n => name.metadata[`formatSuffixLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
|
|
|
|
formats = formatNames.map((n, i) => ({value: n, text: formatLabels[i]}));
|
|
suffixes = suffixNames.map((n, i) => ({value: n, text: suffixLabels[i]}));
|
|
}
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>{name.metadata.name} - Namegen 5</title>
|
|
</svelte:head>
|
|
<Page collection={collection} selected={name.name}>
|
|
<div class="name">
|
|
<h1>{name.metadata.name}</h1>
|
|
<div class="cateogry">{name.metadata.category}</div>
|
|
<div class="description">{name.metadata.description || ""}</div>
|
|
<div style="color: {name.metadata.color || "#eeeeee"}" class:long={result.length > 25} class="result">{result}</div>
|
|
{#if (failed)}
|
|
<div class="failed">Your browser does not support Webassembly, the generator will only pick one out of 30 examples.</div>
|
|
{/if}
|
|
{#if suffixes.length > 0}
|
|
<Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label={name.metadata.formatSuffixType} options={suffixes} bind:value={selectedSuffix} />
|
|
{/if}
|
|
<Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label="Format" prefer="full_" options={formats} bind:value={selectedFormat} />
|
|
|
|
<button disabled={(loaded !== name.name) && !failed} on:click={generate}>Generate</button>
|
|
<div class="footnote">{name.metadata.footnote || ""}</div>
|
|
</div>
|
|
</Page>
|
|
|
|
<style>
|
|
h1 {
|
|
text-align: center;
|
|
margin-bottom: 0;
|
|
line-height: 1em;
|
|
}
|
|
|
|
div.failed {
|
|
color: #fc1;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
div.footnote {
|
|
font-size: 0.9em;
|
|
color: #555;
|
|
margin-top: 2em;
|
|
}
|
|
div.footnote:empty {
|
|
display: none;
|
|
}
|
|
|
|
div.cateogry {
|
|
font-size: 0.75em;
|
|
opacity: 0.75;
|
|
margin-bottom: 1em;
|
|
}
|
|
|
|
div.result {
|
|
border: 1px solid #000;
|
|
border-radius: 0.5em;
|
|
background-color: #333;
|
|
padding: 0.5em 0;
|
|
color: #eee;
|
|
text-align: center;
|
|
font-size: 1.5em;
|
|
min-height: 1.5em;
|
|
}
|
|
div.result.long {
|
|
font-size: 1.25em;
|
|
padding: 0.75em 0;
|
|
|
|
}
|
|
|
|
button {
|
|
background: #333;
|
|
outline: none;
|
|
border: 1px solid #000;
|
|
color: #ccc;
|
|
padding: 0.25em 1ch;
|
|
margin: 1.5em 0 0.5em 0;
|
|
font-size: 1.5em;
|
|
border-radius: 0.5em;
|
|
cursor: pointer;
|
|
box-shadow: 0.025em 0.025em 0.025em #000;
|
|
}
|
|
button:hover {
|
|
color: #fff;
|
|
}
|
|
button:active {
|
|
background: #444;
|
|
box-shadow: none;
|
|
}
|
|
|
|
@media screen and (max-width: 720px) {
|
|
button {
|
|
padding: 0.50em 2ch !important;
|
|
font-size: 1.75em;
|
|
}
|
|
}
|
|
</style>
|